package com.cv.platform.service.subscribe;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cv.framework.common.pojo.PageResult;
import com.cv.framework.common.utils.object.BeanUtils;
import com.cv.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cv.framework.mybatis.core.query.QueryWrapperX;
import com.cv.framework.security.core.utils.SecurityFrameworkUtil;
import com.cv.infra.api.file.FileApi;
import com.cv.platform.controller.platform.subscribe.vo.*;
import com.cv.platform.dal.dataobject.subscribe.CvSubscribeDO;
import com.cv.platform.dal.mapper.subscribe.CvSubscribeMapper;
import com.cv.system.api.user.UserApi;
import com.cv.system.api.user.dto.UserProfileRespDTO;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * 订阅业务层接口实现类
 *
 * @author Charles_XDXD
 */
@Service
public class CvSubscribeServiceImpl implements CvSubscribeService {

    @Resource
    private CvSubscribeMapper cvSubscribeMapper;

    @DubboReference
    private UserApi userApi;

    @DubboReference
    private FileApi fileApi;

    @Override
    public CvSubscribeDetailRespVO getSubscribe(Long targetId) {
        if (ObjUtil.isNotEmpty(targetId)) {
            QueryWrapperX<CvSubscribeDO> wrapper = new QueryWrapperX<CvSubscribeDO>()
                    .eq("subscribe_user_id", SecurityFrameworkUtil.getLoginUserId())
                    .eq("target_user_id", targetId)
                    .eq("deleted", 0);

            CvSubscribeDO cvSubscribeDO = cvSubscribeMapper.selectOne(wrapper);
            if (ObjUtil.isNotEmpty(cvSubscribeDO)) {
                return BeanUtils.toBean(cvSubscribeDO, CvSubscribeDetailRespVO.class);
            }
        }
        return null;
    }

    @Override
    public void saveSubscribe(CvSubscribeSaveReqVO reqVO) {
        if (ObjUtil.isNotEmpty(reqVO)) {
            CvSubscribeDO cvSubscribeDO = BeanUtils.toBean(reqVO, CvSubscribeDO.class);
            cvSubscribeDO.setSubscribeUserId(SecurityFrameworkUtil.getLoginUserId());
            cvSubscribeMapper.insertOrUpdate(cvSubscribeDO);
        }
    }

    @Override
    public void deleteSubscribe(Long id) {
        if (ObjUtil.isNotEmpty(id)) {
            cvSubscribeMapper.deleteById(id);
        }
    }

    @Override
    public void deleteSubscribeByUserId(Long targetId) {
        if (ObjUtil.isNotEmpty(targetId)) {
            QueryWrapperX<CvSubscribeDO> wrapper = new QueryWrapperX<CvSubscribeDO>()
                    .eq("subscribe_user_id", SecurityFrameworkUtil.getLoginUserId())
                    .eq("target_user_id", targetId);
            
            cvSubscribeMapper.delete(wrapper);
        }
    }

    @Override
    public PageResult<CvSubscribeRespVO> selectSubscribePage(CvSubscribeReqVO reqVO) {
        PageResult<CvSubscribeRespVO> pageResult = cvSubscribeMapper.selectPage(reqVO);

        if (CollUtil.isEmpty(pageResult.getList())) {
            return PageResult.empty();
        }

        pageResult.getList().forEach(item -> {
            item.setNickname(userApi.getNicknameById(item.getUserId()));
            item.setAvatarUrl(fileApi.getUrl(userApi.getAvatarById(item.getUserId())));
            item.setThumbnailUrl(fileApi.getUrl(item.getThumbnail()));
        });

        return pageResult;
    }

    @Override
    public Integer getFansCount(Long userId) {
        if (ObjUtil.isNotEmpty(userId)) {
            QueryWrapperX<CvSubscribeDO> wrapper = new QueryWrapperX<CvSubscribeDO>()
                    .eq("target_user_id", userId);

            return Math.toIntExact(cvSubscribeMapper.selectCount(wrapper));
        }
        return null;
    }

    @Override
    public Integer getFollowCount(Long userId) {
        if (ObjUtil.isNotEmpty(userId)) {
            QueryWrapperX<CvSubscribeDO> wrapper = new QueryWrapperX<CvSubscribeDO>()
                    .eq("subscribe_user_id", userId);

            return Math.toIntExact(cvSubscribeMapper.selectCount(wrapper));
        }
        return null;
    }

    @Override
    public PageResult<CvSubscribePageRespVO> getFansPage(CvSubscribePageReqVO reqVO) {
        PageResult<CvSubscribePageRespVO> pageResult = cvSubscribeMapper.selectFansPage(reqVO);

        if (CollUtil.isEmpty(pageResult.getList())) {
            return PageResult.empty();
        }

        pageResult.getList().forEach(item -> {
            UserProfileRespDTO profile = userApi.getProfileById(item.getUserId());
            item.setNickname(userApi.getNicknameById(item.getUserId()));
            item.setAvatar(profile.getAvatar());
            item.setAvatarUrl(fileApi.getUrl(profile.getAvatar()));
            item.setSignature(profile.getSignature());
            item.setIsFollow(ObjUtil.isNotEmpty(getSubscribe(item.getUserId())));
        });

        return pageResult;
    }

    @Override
    public PageResult<CvSubscribePageRespVO> getFollowPage(CvSubscribePageReqVO reqVO) {
        PageResult<CvSubscribePageRespVO> pageResult = cvSubscribeMapper.selectFollowersPage(reqVO);

        if (CollUtil.isEmpty(pageResult.getList())) {
            return PageResult.empty();
        }

        pageResult.getList().forEach(item -> {
            UserProfileRespDTO profile = userApi.getProfileById(item.getUserId());
            item.setNickname(userApi.getNicknameById(item.getUserId()));
            item.setAvatar(profile.getAvatar());
            item.setAvatarUrl(fileApi.getUrl(profile.getAvatar()));
            item.setSignature(profile.getSignature());
            item.setIsFollow(ObjUtil.isNotEmpty(getSubscribe(item.getUserId())));
        });

        return pageResult;
    }

    @Override
    public void deleteAllSubscribe(Long userId) {
        LambdaQueryWrapper<CvSubscribeDO> wrapper = new LambdaQueryWrapperX<CvSubscribeDO>()
                .eq(CvSubscribeDO::getSubscribeUserId, userId)
                .or()
                .eq(CvSubscribeDO::getTargetUserId, userId);
        
        cvSubscribeMapper.delete(wrapper);
    }

}
